-- Copyright (c) 2015,2016 Lucky Byte, Inc.
--
-- Summary : 助农取款交易前处理
--
-- Author  : 吴小虎 <xiaohu@lucky-byte.com>
-- Since   : 2016.7.18
--
-- History
--  * 2015.7.18 : 创建此文件
--  * 2015.7.29 : 完善注释
--

-- 助农取款交易前处理
--  1. 若助农取款代付配置中，'资金池不足以扣除手续费时' 设置为 '不允许助农取款交易'，
--     则需要在转发助农取款交易前进行判定
--
local function _preproc_t60()
    logger.debug('开始执行助农取款交易前处理...')

    -- 从助农取款代付配置中查询当前终端对应的配置记录，查询条件为当前交易终端(助农取款终端)，
    -- 在助农取款代付配置表中，一个助农取款终端只能又一个配置项，因此这里查询结果应是唯一的
    local _t = jdbc.select([[
        select * from pay_p2 where
            usable = true and t60_termid = ? and tz1_termid is not null
    ]], reqt.term.get('uuid'))

    -- 如果查询结果为空，则说明：
    --  1. 此助农取款终端不需要代付；
    --  2. 此助农取款终端需要代付，但系统维护人员忘记为此终端建立助农取款代付配置；
    -- 不论哪种情况，都没有道理拒绝当前的助农取款交易
    if _t.count == 0 then
        logger.debug('终端[%s]没有出现在助农取款代付配置中，允许此助农取款交易.',
            reqt.term.get('termid'))
        return '00'
    end
    -- 查询结果有多条是不可能的，因为数据表建立了唯一约束，这段代码是冗余的
    if _t.count > 1 then
        logger.fatal('助农取款代付配置错误，终端[%s]存在于多条配置记录中.',
            reqt.term.get('termid'))
        return '01'
    end
    local _p2_record = _t.get_record(0)

    logger.debug('终端[%s]出现在助农取款代付配置[%s]中，开始检查其代付配置...',
        reqt.term.get('termid'), _p2_record.get('uuid'))

    -- 如果不是从资金池扣取手续费，则不可能拒绝助农取款交易
    local _fee_take_type  = _p2_record.get('fee_take_type')
    if tonumber(_fee_take_type) ~= 1 then
        return '00'
    end
    -- 如果资金池余额不足以支付手续费时，不拒绝助农取款交易，则返回成功
    local _fund_lack_proc = _p2_record.get('fund_lack_proc')
    if tonumber(_fund_lack_proc) ~= 1 then
        return '00'
    end

    -- 取款金额，此交易金额不可能为空，除非报文错误
    local _tramt = reqt.get_tramt()
    if not _tramt then
        logger.error('助农取款交易金额无效，拒绝此交易.')
        return '05'
    end

    -- 计算助农代付手续费
    -- 助农代付手续费是指助农代付扣取的手续费，这笔手续费在助农取款代付配置中设定
    -- 卡号有可能为空，如果借贷记的手续费率不一样，那么计算的手续费结果可能有偏差，
    -- 避免这个问题的最好办法是终端上送报文必须上送 2 域
    -- 即使这里计算的有偏差，也仅仅影响这里的判定，而不影响实际扣取的手续费，
    -- 因为交易转发后总是可以获取到正确的主账号，因此可以判定卡 BIN.
    local _card_no = reqt.get_pri_acct() or ''
    if string.trimlen(_card_no) == 0 then
        logger.warn('不能获取助农取款请求报文中主账号，将按照默认规则计算手续费...')
    end
    local _p2_fee = core.fee.calc({
        uuid  = _p2_record.get('t60_fee'),
        tramt = _tramt,
        debit = core.cardbin.is_debit(_card_no)
    })

    -- 如果计算手续费失败，拒绝当前的交易
    if _p2_fee < 0 then
        notify.error('计算出助农代付手续费[%s]小于[0.0]，拒绝此助农取款交易，助农取款代付配置为[%s].',
            _p2_fee, _p2_record.get('uuid'))
        return '08'
    end
    -- 如果手续费大于交易金额，拒绝当前的交易
    if _p2_fee > _tramt then
        notify.error('计算出助农代付手续费[%s]大于交易金额[%s]，拒绝此助农取款交易，助农取款代付配置为[%s].',
            _p2_fee, _tramt, _p2_record.get('uuid'))
        return '08'
    end

    -- 查询扣取手续费的资金池
    -- 资金池与助农代付配置关联，每个助农代付配置可以设置自己的资金池
    local _table = jdbc.select([[
        select * from pay_p2_fund where uuid = ?
    ]], _p2_record.get('p2_fund'))

    -- 资金池不应该为空，除非系统配置错误
    if _table.count == 0 then
        logger.error('助农取款代付配置[%s]中的资金池无效.', _p2_record.get('uuid'))
        return '01'
    end
    local _p2_fund = _table.get_record(0)

    -- 如果资金池余额不足以支付手续费，则拒绝当前的助农取款交易
    local _remains = _p2_fund.get('fund_remains')
    if tonumber(_remains) < _p2_fee then
        notify.error(
            '资金池[%s]余额[%s]不足以支付助农代付手续费[%s]，根据配置，拒绝当前助农取款交易.',
            _p2_fund.get('name'), _remains, _p2_fee)
        return '07'
    end
    return '00'
end


return _preproc_t60
